package com.zq.spring.springexpand;

import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;

/**
 * @Author: zhaoqi
 * @Date: 2020/4/29 14:24
 * @Version 1.0
 */
/*
*           BeanFactoryPostProcessor  bean工厂后置处理器   拓展spring的Beanfactory
*           改变bean的定义(BeanFactoryPostProcessor接口) ，可以想象成修改了class文件，这样实例化出来的每个对象都变了；
*           此时可以修改bean的属性，   比如SCOPE    lazy  等
*
*          扩展原理-BeanFactoryPostProcessor
                    BeanPostProcessor：bean后置处理器，bean创建对象初始化前后进行拦截工作的
                    BeanFactoryPostProcessor：beanFactory的后置处理器；
                    在BeanFactory标准初始化之后调用，来定制和修改BeanFactory的内容；
                    所有的bean定义已经保存加载到beanFactory，但是bean的实例还未创建
            BeanFactoryPostProcessor原理:
                    ioc容器创建对象
                    invokeBeanFactoryPostProcessors(beanFactory);
                    如何找到所有的BeanFactoryPostProcessor并执行他们的方法；
                    直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件，并执行他们的方法
                    在初始化创建其他组件前面执行
*
*
*
* */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //AbstractBeanFactory abstractBeanFactory = (AbstractBeanFactory) beanFactory.getBeanDefinition("indexController");
        AbstractBeanDefinition abstractBeanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("indexController");

        MutablePropertyValues pv =  abstractBeanDefinition.getPropertyValues();
        pv.addPropertyValue("desc", "Desc is changed from bean factory post processor");
        abstractBeanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
        abstractBeanDefinition.setLazyInit(true);
        System.out.println(123);
    }

}
